package Leetcode第一期;

/**
 * @author : K k
 * @date : 15:26 2020/9/14
 * 在一个 m*n 的棋盘的每一格都放有一个礼物，每个礼物都有一定的价值（价值大于 0）。你可以从棋盘的左上角开始拿格子里的礼物，并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值，请计算你最多能拿到多少价值的礼物？
 *
 *  
 *
 * 示例 1:
 *
 * 输入:
 * [
 *   [1,3,1],
 *   [1,5,1],
 *   [4,2,1]
 * ]
 * 输出: 12
 * 解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
 */
public class 礼物的最大价值_47 {
    //DFS失败
    /*boolean[][] visited;
    //只需要向下或者向右移动
    int[][] directions=new int[][]{{1,0},{0,1}};
    int[][] grid;
    int ans=0;
    int res=0;
    //回溯
    public int maxValue(int[][] grid) {
        this.grid=grid;
        int n=grid.length;
        int m=grid[0].length;
        this.visited=new boolean[n][m];

        dfsSolver(0,0,n,m);
        return res;
    }

    private void dfsSolver(int n, int m,int nLen,int mLen) {
        if (isArea(n,m,nLen,mLen)){
            //若符合条件
            res+=grid[n][m];
            for (int i=0;i<2;i++){
                //两个方向
                dfsSolver(n+directions[i][0],m+directions[i][1],nLen,mLen);
            }
            res-=grid[n][m];
        }else if( m<=mLen && n<=nLen){
            //若不符合规则
            ans=Math.max(ans,res);
        }

    }

    private boolean isArea(int n, int m,int nLen,int mLen) {
        return n<nLen && n>=0 && m<mLen && m>=0;
    }
*/

    //动态规划
    public int maxValue(int[][] grid) {
        int n=grid.length,m=grid[0].length;
        int[][] dp=new int[n][m];

        for (int i=0;i<n;i++){
            for (int j=0;j<m;j++){
                //只有两个方向，只需要判断左边与上边的元素的大小。
                if (i-1>=0 && j-1>=0){
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1])+grid[i][j];
                }else if (i-1<0 && j-1>=0){
                    dp[i][j]=dp[i][j-1]+grid[i][j];
                }else if(i-1>=0 && j-1<0){
                    dp[i][j]=dp[i-1][j]+grid[i][j];
                }else {
                    dp[i][j]=grid[i][j];
                }
            }
        }
        return dp[n-1][m-1];
    }
    public static void main(String[] args) {
        礼物的最大价值_47 x=new 礼物的最大价值_47();
        System.out.println(x.maxValue(new int[][]{
                {1, 3, 1},
                {1, 5, 1},
                {4, 2, 1}
        }));
    }
}
